package fangpian.leecode

/* 2. 两数相加 [中等]

知识点：链表

给你两个 非空 的链表，表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的，并且每个节点只能存储 一位 数字。
请你将两个数相加，并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外，这两个数都不会以 0 开头。
*/
fun main() {
    class ListNode(var `val`: Int) {
        var next: ListNode? = null
    }

    fun array2ListNode(vararg array: Int): ListNode? {
        if (array.isEmpty()) {
            return null
        }
        val listNode = ListNode(array[0])
        var prev = listNode
        for (i in 1 until array.size) {
            val fuck = ListNode(array[i])
            prev.next = fuck
            prev = fuck
        }
        return listNode
    }

    fun printListNode(listNode: ListNode?) {
        val list = mutableListOf<Int>()
        var point: ListNode? = listNode
        do {
            list.add(point!!.`val`)
            point = point.next
        } while (point != null)
        println(list)
    }

    // 补充完整
    fun addTwoNumbers(l1: ListNode?, l2: ListNode?): ListNode? {
        if (l1 == null || l2 == null) {
            throw Exception()
        }
        // 引入哨兵指针
        val shaobing = ListNode(0)
        var currentL1: ListNode? = l1
        var currentL2: ListNode? = l2
        var currentPoint = shaobing
        // 当前是否有进位
        var carry = 0
        do {
            val n1 = currentL1?.`val` ?: 0
            val n2 = currentL2?.`val` ?: 0
            val sum = n1 + n2 + carry
            carry = sum / 10
            currentPoint.next = ListNode(sum % 10)
            currentPoint = currentPoint.next!!
            currentL1 = currentL1?.next
            currentL2 = currentL2?.next
        } while (carry > 0 || currentL1 != null || currentL2 != null)
        return shaobing.next
    }

    printListNode(addTwoNumbers(array2ListNode(2, 4, 3), array2ListNode(5, 6, 4)))
    printListNode(addTwoNumbers(array2ListNode(0), array2ListNode(0)))
    printListNode(addTwoNumbers(array2ListNode(9,9,9,9,9,9,9), array2ListNode(9,9,9,9)))
}